#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second

const int N=1e6+5;
int n,f[N],rt[N],g[N],ans=0,dep[N],pre[N],d[N];
vector<int> G[N];
bool vis[N];
struct Nod{
  int x,id;
  bool operator <(const Nod &a) const{
	if(x!=a.x) return x<a.x;
	return dep[id]<dep[a.id];
  }
};

priority_queue<Nod> Q[N];

void merge(int u,int v){
  if((int)Q[rt[u]].size()<(int)Q[rt[v]].size()) swap(rt[u],rt[v]);
  while(!Q[rt[v]].empty()) Q[rt[u]].push(Q[rt[v]].top()),Q[rt[v]].pop();
}

int calc(priority_queue<Nod> B){
  priority_queue<Nod> A=B;
  while(!A.empty()){
	int nw=A.top().id;
	if(d[nw]>0) return 1;
	A.pop();
  }
  return 0;
}

void dfs(int u,int fa){
  rt[u]=u,f[u]=1,dep[u]=dep[fa]+1,pre[u]=fa;
  for(auto v:G[u]) if(v!=fa) dfs(v,u);
  if((int)Q[rt[u]].size()>=2){
	auto i=Q[rt[u]].top();
	f[u]+=i.x,vis[i.id]=true,d[pre[i.id]]++,Q[rt[u]].pop();
	i=Q[rt[u]].top();
	f[u]+=i.x,vis[i.id]=true,d[pre[i.id]]++,Q[rt[u]].pop(); 
  }
  ans=max(ans,f[u]+calc(Q[rt[u]]));  
  Q[rt[u]].push({f[u],u});
  merge(fa,u);
}

int main(){
  freopen("bird.in","r",stdin);
  freopen("bird.out","w",stdout);
  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  cin>>n;
  for(int i=1,u,v;i<n;i++) cin>>u>>v,G[u].pb(v),G[v].pb(u);
  dfs(1,0);
  cout<<ans;
  return 0;
}